// DragHWNDLocator.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "DragHWNDLocator.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDragHWNDLocator

CDragHWNDLocator::CDragHWNDLocator()
{
	m_bDown = FALSE;
	m_hFull = 0;
	m_hEmpty = 0;
	m_hNo = 0;
	m_hTarget = 0;
}

CDragHWNDLocator::~CDragHWNDLocator()
{
	if (m_hFull)
		DeleteObject(m_hFull);
	if (m_hEmpty)
		DeleteObject(m_hEmpty);
	if (m_hNo)
		DeleteObject(m_hNo);
	if (m_hTarget)
		DeleteObject(m_hTarget);
}


BEGIN_MESSAGE_MAP(CDragHWNDLocator, CWnd)
	//{{AFX_MSG_MAP(CDragHWNDLocator)
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CDragHWNDLocator message handlers

BOOL CDragHWNDLocator::Create(const RECT & rect, CWnd * pParent)
{
	LPCTSTR szClass = ::AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW,::AfxGetApp()->LoadStandardCursor(IDC_ARROW),(HBRUSH)GetSysColorBrush(NULL_BRUSH),0);
	m_hFull = (HICON)LoadImage(GetModuleHandle(0),MAKEINTRESOURCE(IDI_FULL),IMAGE_ICON,0,0,LR_SHARED);
	m_hEmpty = (HICON)LoadImage(GetModuleHandle(0),MAKEINTRESOURCE(IDI_EMPTY),IMAGE_ICON,0,0,LR_SHARED);
	m_hTarget = LoadCursor(GetModuleHandle(0),MAKEINTRESOURCE(IDC_TARGET));
	m_hNo = LoadCursor(0,IDC_NO);
	return CWnd::Create(szClass,0,WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS,rect,pParent,0);
}

void CDragHWNDLocator::OnLButtonDown(UINT nFlags, CPoint point) 
{
	OutputDebugString("OnLButtonDown\r\n");
	m_bDown = TRUE;
	SetCapture();
	//SetCursor();
	hSelectedWnd = 0;//GetParent()->GetSafeHwnd();
	//HighlightWindow(hSelectedWnd);
	CWnd::OnLButtonDown(nFlags, point);
	Invalidate(FALSE);
}

void CDragHWNDLocator::OnLButtonUp(UINT nFlags, CPoint point) 
{
	OutputDebugString("OnLButtonUp\r\n");
	m_bDown = FALSE;
	::GetCursorPos(&point);
	SetCursor(LoadCursor(0,IDC_ARROW));
	ReleaseCapture();
	
	if (hSelectedWnd)
	{
		GetParent()->PostMessage(WM_GIVEHWND,0,(LPARAM)hSelectedWnd);
	}
	HighlightWindow(hSelectedWnd);
	CWnd::OnLButtonUp(nFlags, point);
	Invalidate(FALSE);
}

void CDragHWNDLocator::HighlightWindow(HWND hWnd)
{
	HDC hDC = ::GetWindowDC(hWnd);
	if (hDC)
	{
		int nOldR2Not = SetROP2(hDC,R2_NOT);
		if (nOldR2Not)
		{
			HPEN hPen = CreatePen(PS_INSIDEFRAME,3,0);
			HBRUSH hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
			
			if (hPen && hBrush)
			{
				HPEN hOldPen = (HPEN)SelectObject(hDC,hPen);
				HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC,hBrush);

				HRGN hRgn = CreateRectRgn(0,0,0,0);
				
				if ( ::GetWindowRgn(hWnd, hRgn))
				{
					HBRUSH hHatchBrush = CreateHatchBrush(HS_DIAGCROSS,GetSysColor(COLOR_WINDOWFRAME));

					FrameRgn(hDC,hRgn,hHatchBrush,3,3);

					DeleteObject(hHatchBrush);
				}
				else
				{
					RECT rect;
					::GetWindowRect(hWnd,&rect);
					rect.right -= rect.left;
					rect.bottom -= rect.top;
					rect.left = 0;
					rect.top = 0;
					if ( ::IsZoomed(hWnd) )
					{
						InflateRect(&rect,-3,-3);
					}
					Rectangle(hDC,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top);
				}
			
				SelectObject(hDC,hOldPen);
				SelectObject(hDC,hOldBrush);

				DeleteObject(hRgn);
				DeleteObject(hPen);
				DeleteObject(hBrush);
			}

			DeleteObject(hPen);
			SetROP2(hDC,nOldR2Not);
		}
		::ReleaseDC(hWnd,hDC);	
	}
}


void CDragHWNDLocator::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (!m_bDown)
		return;
	OutputDebugString("OnLButtonMove\r\n");
	GetCursorPos(&point);
	char szClass[200] = {0};
	DWORD dwTime = GetTickCount();
	HWND hWnd = ::WindowFromPoint(point);
	if (hWnd)
	{
		GetClassName(hWnd,szClass,200);
		if (strcmp(szClass,"DirectUIHWND")==0 || strcmp(szClass, "WLXDUI")==0)
		{
			SetCursor(m_hTarget);
			if (hWnd!=hSelectedWnd)
			{
				HighlightWindow(hSelectedWnd);
				HighlightWindow(hWnd);
				hSelectedWnd = hWnd;
			}
		}
		else
		{
			if (hSelectedWnd)
				HighlightWindow(hSelectedWnd);
			hSelectedWnd = 0;
			SetCursor(m_hNo);
		}
		dwTime = GetTickCount()-dwTime;
		CString s;
		s.Format("dwTime: %u\r\n",dwTime);
		OutputDebugString(s);
	}
	//while (::GetParent(hWnd))
	//	hWnd = ::GetParent(hWnd);

	CWnd::OnMouseMove(nFlags, point);
}

void CDragHWNDLocator::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	CRect rect;
	GetClientRect(rect);
	dc.FillSolidRect(rect,GetSysColor(COLOR_BTNFACE));

	DrawIcon(dc.m_hDC,0,0,m_bDown?m_hEmpty:m_hFull);
	// Do not call CWnd::OnPaint() for painting messages
}

BOOL CDragHWNDLocator::OnEraseBkgnd(CDC* pDC) 
{
	CRect rect;
	GetClientRect(rect);
	pDC->FillSolidRect(rect,GetSysColor(COLOR_BTNFACE));
	return TRUE;
	//return CWnd::OnEraseBkgnd(pDC);
}
